package com.sanpu.kxe.rxservice;

import android.support.v4.util.Pair;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSONObject;
import com.sanpu.kxe.common.interfaces.CommonConfig;
import com.sanpu.kxe.common.interfaces.UrlConstants;
import com.sanpu.kxe.utils.TimeManager;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import rx.Observable;
import rx.functions.Func1;

/**
 * Description：网络接口基类 retrofit2 & RxJava & Http
 * Created by 薛勇军 on 2018/6/14.
 */

public class BaseClient {
    private HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    protected OkHttpClient client;
    private Interceptor headInterceptor;

    protected BaseClient() {
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        headInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request()
                        .newBuilder()
                        .addHeader("timestamp", String.valueOf(TimeManager.getInstance().getCurTimeMillis()))
                        .build();
                return chain.proceed(request);
            }
        };

        client = new OkHttpClient.Builder()
                .addInterceptor(logging)
                .addInterceptor(headInterceptor)
                .readTimeout(UrlConstants.HTTP_TIMEOUT, TimeUnit.SECONDS)
                .connectTimeout(UrlConstants.HTTP_TIMEOUT, TimeUnit.SECONDS)
                .build();
    }

    /**
     * 登录前 response处理
     */
    protected Observable<Pair<MetaBean, String>> callMapBeforeLogin(Observable<MetaBean> observable) {
        return callMap(observable, true);
    }

    /**
     * 登录后 response处理
     */
    protected Observable<Pair<MetaBean, String>> callMapAfterLogin(Observable<MetaBean> observable) {
        return callMap(observable, false);
    }

    /**
     * response处理
     *
     * @param observable 对象
     */
    private Observable<Pair<MetaBean, String>> callMap(Observable<MetaBean> observable, final boolean isPublicKey) {
        return observable.map(new Func1<MetaBean, Pair<MetaBean, String>>() {
            @Override
            public Pair<MetaBean, String> call(MetaBean metaBean) {
                if (metaBean == null) {
                    return null;
                }
                if (TextUtils.equals(CommonConfig.RET_OK, metaBean.getRespCode())) {
                    if (!TextUtils.isEmpty(metaBean.getRespData())) {
                        //解密
                        try {
                            String respData = DataUtils.dataDecode(metaBean.getRespData(), isPublicKey);
                            Log.e(metaBean.getRespMsg(), respData);
                            return new Pair<>(metaBean, respData);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return new Pair<>(metaBean, null);
                    }
                }
                return new Pair<>(metaBean, "");
            }
        });
    }

    /**
     * response处理
     *
     * @param observable 对象
     */
    public Observable<Pair<MetaBean, JSONObject>> callMap(Observable<JSONObject> observable) {
        return observable.map(new Func1<JSONObject, Pair<MetaBean, JSONObject>>() {
            @Override
            public Pair<MetaBean, JSONObject> call(JSONObject metaBean) {
                if (metaBean == null) {
                    return null;
                }
                return new Pair<>(new MetaBean(), metaBean);
            }
        });
    }

    /**
     * 创建Obserable
     */
    public <T> Observable<T> toObservable(Pair<MetaBean, T> pair) {
        if (pair == null || pair.first == null) {
            return Observable.error(RxError.create(RxError.ERROR_UNKNOWN, RxError.ERROR_UNKNOWN));
        }
        if (TextUtils.equals(CommonConfig.RET_OK, pair.first.getRespCode())) {
            return Observable.just(pair.second);
        }
        if (TextUtils.equals(CommonConfig.OFFLINE, pair.first.getRespCode())) {
            return Observable.error(RxError.create(RxError.ERROR_OFFLINE, pair.first.getRespCode(),
                    pair.first.getRespMsg()));
        }
        return Observable.error(RxError.create(RxError.ERROR_TYPE_DATA, pair.first.getRespCode(),
                pair.first.getRespMsg()));
    }

    /**
     * 文件上传处理
     * @param filePaths 文件地址集合
     */
    protected List<MultipartBody.Part> files2Parts(HashMap<String, File> filePaths) {
        List<MultipartBody.Part> parts = new ArrayList<>(filePaths.size());
        for (Map.Entry<String, File> entry : filePaths.entrySet()) {
            File file = entry.getValue();
            RequestBody requestBody = RequestBody.create(MediaType.parse("image"), file);
            MultipartBody.Part part = MultipartBody.Part.
                    createFormData(entry.getKey(), file.getName(), requestBody);
            parts.add(part);
        }
        return parts;
    }
}
